package com.castle.fortress.admin.argFlow.controller;

import com.castle.fortress.admin.argFlow.constants.RAGFlowApiConstants;
import com.castle.fortress.admin.argFlow.dto.*;
import com.castle.fortress.admin.argFlow.service.RAGFlowService;
import com.castle.fortress.admin.member.member.entity.MemberEntity;
import com.castle.fortress.admin.member.member.service.MemberService;
import com.castle.fortress.admin.utils.WebUtil;
import com.castle.fortress.common.exception.BizException;
import com.castle.fortress.common.respcode.GlobalRespCode;
import com.castle.fortress.admin.system.entity.ConfigParamsEntity;
import com.castle.fortress.admin.system.service.ConfigParamsService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.*;

/**
 * RAGFlow API控制器
 */
@Api(tags = "RAG流程控制器")
@RestController
@RequestMapping(RAGFlowApiConstants.API_BASE_PATH)
@Slf4j
public class RAGFlowController {

    @Autowired
    private RAGFlowService ragFlowService;

    @Autowired
    private MemberService memberService;

    @Autowired
    private ConfigParamsService configParamsService;

    /**
     * 创建数据集
     *
     * @param request 创建数据集请求
     * @return 数据集响应
     */
    @ApiOperation("创建数据集")
    @PostMapping("/datasets")
    public ResponseDTO<DatasetResponseDTO.DatasetData> createDataset(
            @ApiParam(value = "创建数据集请求", required = true) @RequestBody Map<String, Object> request) {
        DatasetRequestDTO datasetRequest = new DatasetRequestDTO();
        datasetRequest.setName((String) request.get("name"));
        datasetRequest.setAvatar((String) request.get("avatar"));
        datasetRequest.setDescription((String) request.get("description"));
        datasetRequest.setLanguage((String) request.get("language"));
        datasetRequest.setEmbedding_model((String) request.get("embedding_model"));
        datasetRequest.setPermission((String) request.get("permission"));
        datasetRequest.setChunk_method((String) request.get("chunk_method"));
        @SuppressWarnings("unchecked")
        Map<String, Object> parserConfig = (Map<String, Object>) request.get("parser_config");
        datasetRequest.setParser_config(parserConfig);
        return ragFlowService.createDataset(datasetRequest);
    }

    /**
     * 获取数据集
     *
     * @param datasetId 数据集ID
     * @return 数据集响应
     */
    @ApiOperation("获取数据集")
    @GetMapping("/datasets/{datasetId}")
    public ResponseDTO<DatasetResponseDTO.DatasetData> getDataset(
            @ApiParam(value = "数据集ID", required = true) @PathVariable String datasetId) {
        return ragFlowService.getDataset(datasetId);
    }

    /**
     * 获取数据集列表
     *
     * @param page 页码
     * @param pageSize 每页大小
     * @param orderBy 排序字段
     * @param desc 是否降序
     * @param name 数据集名称
     * @param id 数据集ID
     * @return 数据集列表响应
     */
    @ApiOperation("获取数据集列表")
    @GetMapping("/datasets")
    public ResponseDTO<Map<String, Object>> listDatasets(
            @ApiParam(value = "页码") @RequestParam(required = false, defaultValue = "1") Integer page,
            @ApiParam(value = "每页大小") @RequestParam(required = false, defaultValue = "30") Integer pageSize,
            @ApiParam(value = "排序字段") @RequestParam(required = false) String orderBy,
            @ApiParam(value = "是否降序") @RequestParam(required = false) Boolean desc,
            @ApiParam(value = "数据集名称") @RequestParam(required = false) String name,
            @ApiParam(value = "数据集ID") @RequestParam(required = false) String id) {
        return ragFlowService.listDatasets(page, pageSize, orderBy, desc, name, id);
    }

    /**
     * 删除数据集
     *
     * @param datasetId 数据集ID
     * @return 响应结果
     */
    @ApiOperation("删除数据集")
    @DeleteMapping("/datasets/{datasetId}")
    public ResponseDTO<Void> deleteDataset(
            @ApiParam(value = "数据集ID", required = true) @PathVariable String datasetId) {
        return ragFlowService.deleteDataset(datasetId);
    }

    /**
     * 批量删除数据集
     *
     * @param request 包含数据集ID列表的请求
     * @return 响应结果
     */
    @ApiOperation("批量删除数据集")
    @DeleteMapping("/datasets")
    public ResponseDTO<Void> batchDeleteDatasets(
            @ApiParam(value = "数据集ID列表", required = true) @RequestBody Map<String, List<String>> request) {
        List<String> datasetIds = request.get("ids");
        // 如果未提供IDs，返回错误
        if (datasetIds == null || datasetIds.isEmpty()) {
            return ResponseDTO.error(RAGFlowApiConstants.ERROR_CODE_COMMON, "未提供要删除的数据集ID");
        }

        // 遍历删除每个数据集
        for (String datasetId : datasetIds) {
            ResponseDTO<Void> response = ragFlowService.deleteDataset(datasetId);
            // 如果删除某个数据集失败，立即返回错误
            if (response.getCode() != RAGFlowApiConstants.SUCCESS_CODE) {
                return response;
            }
        }

        return ResponseDTO.success();
    }

    /**
     * 上传文档
     *
     * @param datasetId 数据集ID
     * @param type 文档类型
     * @param chunkMethod 分块方法
     * @param parserConfig 解析配置
     * @return 响应结果
     */
    @ApiOperation("上传文档")
    @PostMapping("/datasets/{datasetId}/documents")
    public ResponseDTO<Map<String, Object>> uploadDocument(
            @ApiParam(value = "数据集ID", required = true) @PathVariable String datasetId,
            @ApiParam(value = "文件", required = true) @RequestParam MultipartFile file,
            @ApiParam(value = "文档类型") @RequestParam(required = false, defaultValue = "doc") String type,
            @ApiParam(value = "分块方法") @RequestParam(required = false, defaultValue = "naive") String chunkMethod,
            @ApiParam(value = "解析配置") @RequestParam(required = false) String parserConfig) {
        return ragFlowService.uploadDocument(datasetId, file, type, chunkMethod, parserConfig);
    }

    /**
     * 下载文档
     *
     * 根据数据集ID和文档ID下载指定文档
     * 响应将设置适当的Content-Type和Content-Disposition头
     * 文件将直接写入响应流
     *
     * @param datasetId 数据集ID
     * @param documentId 文档ID
     * @param response HTTP响应，用于写入文件内容
     */
    @ApiOperation(value = "下载文档", notes = "下载指定的文档文件，返回文件的二进制内容")
    @GetMapping("/datasets/{datasetId}/documents/{documentId}")
    public void downloadDocument(
            @ApiParam(value = "数据集ID", required = true) @PathVariable String datasetId,
            @ApiParam(value = "文档ID", required = true) @PathVariable String documentId,
            HttpServletResponse response) {
        ragFlowService.downloadDocument(datasetId, documentId, response);
    }

    /**
     * 获取文档列表
     *
     * 根据数据集ID获取文档列表，支持分页、排序和筛选
     *
     * @param datasetId 数据集ID
     * @param page 页码，默认为1
     * @param pageSize 每页大小，默认为30
     * @param orderBy 排序字段，可选值：create_time(默认)、update_time
     * @param desc 是否降序，默认为true
     * @param keywords 用于匹配文档标题的关键词
     * @param id 要检索的文档的ID
     * @param name 文档名称
     * @return 文档列表响应，包含文档信息和总数
     */
    @ApiOperation(value = "获取文档列表", notes = "获取指定数据集中的文档列表，支持分页、排序和多种筛选条件")
    @GetMapping("/datasets/{datasetId}/documents")
    public ResponseDTO<DocumentResponseDTO.DocumentData> listDocuments(
            @ApiParam(value = "数据集ID", required = true) @PathVariable String datasetId,
            @ApiParam(value = "页码，默认为1") @RequestParam(required = false, defaultValue = "1") Integer page,
            @ApiParam(value = "每页大小，默认为30") @RequestParam(required = false, defaultValue = "30") Integer pageSize,
            @ApiParam(value = "排序字段，可选值：create_time(默认)、update_time") @RequestParam(required = false) String orderBy,
            @ApiParam(value = "是否降序，默认为true") @RequestParam(required = false) Boolean desc,
            @ApiParam(value = "用于匹配文档标题的关键词") @RequestParam(required = false) String keywords,
            @ApiParam(value = "要检索的文档的ID") @RequestParam(required = false) String id,
            @ApiParam(value = "文档名称") @RequestParam(required = false) String name) {
        return ragFlowService.listDocuments(datasetId, page, pageSize, orderBy, desc, keywords, id, name);
    }

    /**
     * 删除文档
     *
     * @param datasetId 数据集ID
     * @param request 文档ID列表请求
     * @return 响应结果
     */
    @ApiOperation("删除文档")
    @DeleteMapping("/datasets/{datasetId}/documents")
    public ResponseDTO<Void> deleteDocuments(
            @ApiParam(value = "数据集ID", required = true) @PathVariable String datasetId,
            @ApiParam(value = "文档ID列表", required = true) @RequestBody Map<String, List<String>> request) {
        return ragFlowService.deleteDocuments(datasetId, request.get("ids"));
    }

    /**
     * 解析文档
     *
     * @param datasetId 数据集ID
     * @param request 文档ID列表请求
     * @return 响应结果
     */
    @ApiOperation("解析文档")
    @PostMapping("/datasets/{datasetId}/chunks")
    public ResponseDTO<Void> parseDocuments(
            @ApiParam(value = "数据集ID", required = true) @PathVariable String datasetId,
            @ApiParam(value = "文档ID列表", required = true) @RequestBody Map<String, List<String>> request) {
        return ragFlowService.parseDocuments(datasetId, request.get("document_ids"));
    }

    /**
     * 停止解析文档
     *
     * @param datasetId 数据集ID
     * @param request 文档ID列表请求
     * @return 响应结果
     */
    @ApiOperation("停止解析文档")
    @DeleteMapping("/datasets/{datasetId}/chunks")
    public ResponseDTO<Void> stopParsingDocuments(
            @ApiParam(value = "数据集ID", required = true) @PathVariable String datasetId,
            @ApiParam(value = "文档ID列表", required = true) @RequestBody Map<String, List<String>> request) {
        return ragFlowService.stopParsingDocuments(datasetId, request.get("document_ids"));
    }

    /**
     * 更新数据集
     *
     * @param datasetId 数据集ID
     * @param request 更新数据集请求
     * @return 数据集响应
     */
    @ApiOperation("更新数据集")
    @PutMapping("/datasets/{datasetId}")
    public ResponseDTO<DatasetResponseDTO.DatasetData> updateDataset(
            @ApiParam(value = "数据集ID", required = true) @PathVariable String datasetId,
            @ApiParam(value = "更新数据集请求", required = true) @RequestBody Map<String, Object> request) {
        DatasetRequestDTO datasetRequest = new DatasetRequestDTO();
        // 只保留API文档中定义的三个字段
        datasetRequest.setName((String) request.get("name"));
        datasetRequest.setEmbedding_model((String) request.get("embedding_model"));
        datasetRequest.setChunk_method((String) request.get("chunk_method"));
        return ragFlowService.updateDataset(datasetId, datasetRequest);
    }

    /**
     * 更新文档
     *
     * @param datasetId 数据集ID
     * @param documentId 文档ID
     * @param request 更新文档请求
     * @return 响应结果
     */
    @ApiOperation("更新文档")
    @PutMapping("/datasets/{datasetId}/documents/{documentId}")
    public ResponseDTO<Map<String, Object>> updateDocument(
            @ApiParam(value = "数据集ID", required = true) @PathVariable String datasetId,
            @ApiParam(value = "文档ID", required = true) @PathVariable String documentId,
            @ApiParam(value = "更新文档请求", required = true) @RequestBody Map<String, Object> request) {
        DocumentRequestDTO documentRequest = new DocumentRequestDTO();
        documentRequest.setName((String) request.get("name"));
        documentRequest.setType((String) request.get("type"));
        documentRequest.setChunk_method((String) request.get("chunk_method"));
        @SuppressWarnings("unchecked")
        Map<String, Object> parserConfig = (Map<String, Object>) request.get("parser_config");
        documentRequest.setParser_config(parserConfig);
        return ragFlowService.updateDocument(datasetId, documentId, documentRequest);
    }

    /**
     * 添加块
     *
     * @param datasetId 数据集ID
     * @param request 添加块请求
     * @return 块响应
     */
    @ApiOperation("添加块")
    @PostMapping("/datasets/{datasetId}/chunks/add")
    public ResponseDTO<Map<String, Object>> addChunk(
            @ApiParam(value = "数据集ID", required = true) @PathVariable String datasetId,
            @ApiParam(value = "添加块请求", required = true) @RequestBody Map<String, Object> request) {
        ChunkRequestDTO chunkRequest = new ChunkRequestDTO();
        chunkRequest.setContent((String) request.get("content"));
        @SuppressWarnings("unchecked")
        Map<String, Object> metadata = (Map<String, Object>) request.get("metadata");
        chunkRequest.setMetadata(metadata);
        return ragFlowService.addChunk(datasetId, chunkRequest);
    }

    /**
     * 获取块列表
     *
     * @param datasetId 数据集ID
     * @param page 页码
     * @param pageSize 每页大小
     * @param documentId 文档ID
     * @return 块列表响应
     */
    @ApiOperation("获取块列表")
    @GetMapping("/datasets/{datasetId}/chunks")
    public ResponseDTO<ChunkResponseDTO.ChunkData> listChunks(
            @ApiParam(value = "数据集ID", required = true) @PathVariable String datasetId,
            @ApiParam(value = "页码") @RequestParam(required = false, defaultValue = "1") Integer page,
            @ApiParam(value = "每页大小") @RequestParam(required = false, defaultValue = "30") Integer pageSize,
            @ApiParam(value = "文档ID") @RequestParam(required = false) String documentId) {
        return ragFlowService.listChunks(datasetId, page, pageSize, documentId);
    }

    /**
     * 更新块
     *
     * @param datasetId 数据集ID
     * @param chunkId 块ID
     * @param request 更新块请求
     * @return 块响应
     */
    @ApiOperation("更新块")
    @PutMapping("/datasets/{datasetId}/chunks/{chunkId}")
    public ResponseDTO<Map<String, Object>> updateChunk(
            @ApiParam(value = "数据集ID", required = true) @PathVariable String datasetId,
            @ApiParam(value = "块ID", required = true) @PathVariable String chunkId,
            @ApiParam(value = "更新块请求", required = true) @RequestBody Map<String, Object> request) {
        ChunkRequestDTO chunkRequest = new ChunkRequestDTO();
        chunkRequest.setContent((String) request.get("content"));
        @SuppressWarnings("unchecked")
        Map<String, Object> metadata = (Map<String, Object>) request.get("metadata");
        chunkRequest.setMetadata(metadata);
        return ragFlowService.updateChunk(datasetId, chunkId, chunkRequest);
    }

    /**
     * 删除块
     *
     * @param datasetId 数据集ID
     * @param request 块ID列表请求
     * @return 响应结果
     */
    @ApiOperation("删除块")
    @DeleteMapping("/datasets/{datasetId}/chunks/delete")
    public ResponseDTO<Void> deleteChunks(
            @ApiParam(value = "数据集ID", required = true) @PathVariable String datasetId,
            @ApiParam(value = "块ID列表", required = true) @RequestBody Map<String, List<String>> request) {
        return ragFlowService.deleteChunks(datasetId, request.get("ids"));
    }

    /**
     * 检索块
     *
     * @param datasetId 数据集ID
     * @param request 检索块请求
     * @return 块列表响应
     */
    @ApiOperation("检索块")
    @PostMapping("/datasets/{datasetId}/search")
    public ResponseDTO<ChunkResponseDTO.ChunkData> searchChunks(
            @ApiParam(value = "数据集ID", required = true) @PathVariable String datasetId,
            @ApiParam(value = "检索块请求", required = true) @RequestBody Map<String, Object> request) {
        ChunkRequestDTO chunkRequest = new ChunkRequestDTO();
        chunkRequest.setQuery((String) request.get("query"));
        chunkRequest.setTop_k((Integer) request.get("top_k"));
        chunkRequest.setMetadata((Map<String, Object>) request.get("metadata"));
        chunkRequest.setSimilarity_threshold((Double) request.get("similarity_threshold"));
        return ragFlowService.searchChunks(datasetId, chunkRequest);
    }

    /**
     * 创建聊天助手
     *
     * @param request 创建聊天助手请求
     * @return 聊天助手响应
     */
    @ApiOperation("创建聊天助手")
    @PostMapping("/assistants")
    public ResponseDTO<Map<String, Object>> createAssistant(
            @ApiParam(value = "创建聊天助手请求", required = true) @RequestBody Map<String, Object> request) {
        AssistantRequestDTO assistantRequest = new AssistantRequestDTO();
        assistantRequest.setName((String) request.get("name"));
        assistantRequest.setDescription((String) request.get("description"));
        assistantRequest.setModel((String) request.get("model"));
        assistantRequest.setInstructions((String) request.get("instructions"));
        // 把数组类型转换为List
        @SuppressWarnings("unchecked")
        List<String> datasetIds = (List<String>) request.get("dataset_ids");
        assistantRequest.setDataset_ids(datasetIds);
        return ragFlowService.createAssistant(assistantRequest);
    }

    /**
     * 获取聊天助手
     *
     * @param assistantId 聊天助手ID
     * @return 聊天助手响应
     */
    @ApiOperation("获取聊天助手")
    @GetMapping("/assistants/{assistantId}")
    public ResponseDTO<Map<String, Object>> getAssistant(
            @ApiParam(value = "聊天助手ID", required = true) @PathVariable String assistantId) {
        return ragFlowService.getAssistant(assistantId);
    }

    /**
     * 更新聊天助手
     *
     * @param assistantId 聊天助手ID
     * @param request 更新聊天助手请求
     * @return 聊天助手响应
     */
    @ApiOperation("更新聊天助手")
    @PutMapping("/assistants/{assistantId}")
    public ResponseDTO<Map<String, Object>> updateAssistant(
            @ApiParam(value = "聊天助手ID", required = true) @PathVariable String assistantId,
            @ApiParam(value = "更新聊天助手请求", required = true) @RequestBody Map<String, Object> request) {
        AssistantRequestDTO assistantRequest = new AssistantRequestDTO();
        assistantRequest.setName((String) request.get("name"));
        assistantRequest.setDescription((String) request.get("description"));
        assistantRequest.setModel((String) request.get("model"));
        assistantRequest.setInstructions((String) request.get("instructions"));
        // 把数组类型转换为List
        @SuppressWarnings("unchecked")
        List<String> datasetIds = (List<String>) request.get("dataset_ids");
        assistantRequest.setDataset_ids(datasetIds);
        return ragFlowService.updateAssistant(assistantId, assistantRequest);
    }

    /**
     * 删除聊天助手
     *
     * @param assistantId 聊天助手ID
     * @return 响应结果
     */
    @ApiOperation("删除聊天助手")
    @DeleteMapping("/assistants/{assistantId}")
    public ResponseDTO<Void> deleteAssistant(
            @ApiParam(value = "聊天助手ID", required = true) @PathVariable String assistantId) {
        return ragFlowService.deleteAssistant(assistantId);
    }

    /**
     * 获取聊天助手列表
     *
     * 获取所有聊天助手的列表，支持分页、排序和筛选
     *
     * @param page 页码，默认为1
     * @param pageSize 每页大小，默认为30
     * @param orderBy 排序字段，可选值：create_time(默认)、update_time
     * @param desc 是否降序，默认为true
     * @param name 要检索的聊天助手名称
     * @param id 要检索的聊天助手ID
     * @return 聊天助手列表响应，包含聊天助手信息和总数
     */
    @ApiOperation(value = "获取聊天助手列表", notes = "获取聊天助手列表，支持分页、排序和多种筛选条件")
    @GetMapping("/chats")
    public ResponseDTO<Map<String, Object>> listChats(
            @ApiParam(value = "页码，默认为1") @RequestParam(required = false, defaultValue = "1") Integer page,
            @ApiParam(value = "每页大小，默认为30") @RequestParam(required = false, defaultValue = "30") Integer pageSize,
            @ApiParam(value = "排序字段，可选值：create_time(默认)、update_time") @RequestParam(required = false) String orderBy,
            @ApiParam(value = "是否降序，默认为true") @RequestParam(required = false) Boolean desc,
            @ApiParam(value = "要检索的聊天助手名称") @RequestParam(required = false) String name,
            @ApiParam(value = "要检索的聊天助手ID") @RequestParam(required = false) String id) {
        return ragFlowService.listChats(page, pageSize, orderBy, desc, name, id);
    }

    /**
     * 创建聊天会话
     *
     * 为指定的聊天助手创建一个新会话
     *
     * @param chatId 聊天助手ID
     * @param request 创建会话请求
     * @return 会话响应，包含会话信息和初始消息
     */
    @ApiOperation(value = "创建聊天会话", notes = "为指定的聊天助手创建一个新会话")
    @PostMapping("/chats/{chatId}/sessions")
    public ResponseDTO<Map<String, Object>> createSession(
            @ApiParam(value = "聊天助手ID", required = true) @PathVariable String chatId,
            @ApiParam(value = "创建会话请求", required = true) @RequestBody Map<String, Object> request) {
        SessionRequestDTO sessionRequest = new SessionRequestDTO();
        sessionRequest.setName((String) request.get("name"));
        sessionRequest.setUserId((String) request.get("userId"));
        //TODO 登录用户
        String userId = getUserId();
        if (userId != null) {
            sessionRequest.setUserId(userId);
        }
        return ragFlowService.createSession(chatId, sessionRequest);
    }

    /**
     * 更新聊天会话
     *
     * 更新指定聊天助手的指定会话
     *
     * @param chatId 聊天助手ID
     * @param sessionId 会话ID
     * @param request 更新会话请求
     * @return 响应结果
     */
    @ApiOperation(value = "更新聊天会话", notes = "更新指定聊天助手的指定会话")
    @PutMapping("/chats/{chatId}/sessions/{sessionId}")
    public ResponseDTO<Void> updateSession(
            @ApiParam(value = "聊天助手ID", required = true) @PathVariable String chatId,
            @ApiParam(value = "会话ID", required = true) @PathVariable String sessionId,
            @ApiParam(value = "更新会话请求", required = true) @RequestBody Map<String, Object> request) {
        SessionRequestDTO sessionRequest = new SessionRequestDTO();
        sessionRequest.setName((String) request.get("name"));
        sessionRequest.setUserId((String) request.get("userId"));
        //TODO 登录用户
        String userId = getUserId();
        if (userId != null) {
            sessionRequest.setUserId(userId);
        }
        return ragFlowService.updateSession(chatId, sessionId, sessionRequest);
    }

    /**
     * 获取聊天会话列表
     *
     * @param chatId 聊天助手ID
     * @param page 页码，默认为1
     * @param pageSize 每页大小，默认为30
     * @param orderBy 排序字段，可选值：create_time(默认)、update_time
     * @param desc 是否降序，默认为true
     * @param name 要检索的会话名称
     * @param id 要检索的会话ID
     * @param userId 要检索的用户ID
     * @return 会话列表响应，包含会话信息和消息
     */
    @ApiOperation(value = "获取聊天会话列表", notes = "获取指定聊天助手的所有会话列表，支持分页、排序和多种筛选条件")
    @GetMapping("/chats/{chatId}/sessions")
    public ResponseDTO<List<Map<String, Object>>> listSessions(
            @ApiParam("聊天ID") @PathVariable String chatId,
            @ApiParam("页码") @RequestParam(defaultValue = "1") Integer page,
            @ApiParam("每页大小") @RequestParam(defaultValue = "10") Integer pageSize,
            @ApiParam("排序字段") @RequestParam(required = false) String orderBy,
            @ApiParam("是否降序") @RequestParam(defaultValue = "false") Boolean desc,
            @ApiParam("会话名称") @RequestParam(required = false) String name,
            @ApiParam("会话ID") @RequestParam(required = false) String id,
            @ApiParam("用户ID") @RequestParam(required = false) String userId) {
        try {
            //TODO 登录用户
            String currentUserId = getUserId();
            if (userId != null) {
                userId = currentUserId;
            }
            return ragFlowService.listSessions(chatId, page, pageSize, orderBy, desc, name, id, userId);
        } catch (Exception e) {
            log.error("获取会话列表失败", e);
            return ResponseDTO.error(RAGFlowApiConstants.ERROR_CODE_COMMON, "获取会话列表失败：" + e.getMessage());
        }
    }

    /**
     * 获取默认聊天助手会话列表
     *
     * @param page 页码，默认为1
     * @param pageSize 每页大小，默认为30
     * @param orderBy 排序字段，可选值：create_time(默认)、update_time
     * @param desc 是否降序，默认为true
     * @param name 要检索的会话名称
     * @param id 要检索的会话ID
     * @param userId 要检索的用户ID
     * @return 会话列表响应，包含会话信息和消息
     */
    @ApiOperation(value = "获取默认聊天助手会话列表", notes = "获取系统默认聊天助手的所有会话列表，支持分页、排序和多种筛选条件")
    @GetMapping("/chats/default/sessions")
    public ResponseDTO<List<Map<String, Object>>> listDefaultSessions(
            @ApiParam("页码") @RequestParam(defaultValue = "1") Integer page,
            @ApiParam("每页大小") @RequestParam(defaultValue = "10") Integer pageSize,
            @ApiParam("排序字段") @RequestParam(required = false) String orderBy,
            @ApiParam("是否降序") @RequestParam(defaultValue = "false") Boolean desc,
            @ApiParam("会话名称") @RequestParam(required = false) String name,
            @ApiParam("会话ID") @RequestParam(required = false) String id,
            @ApiParam("用户ID") @RequestParam(required = false) String userId) {
        try {
            // 获取默认chatId
            QueryWrapper<ConfigParamsEntity> wrapper = new QueryWrapper<>();
            wrapper.eq("param_code", "defaultChat");
            wrapper.last("limit 1");
            ConfigParamsEntity entity = configParamsService.getOne(wrapper);

            if (entity == null || entity.getParamValue() == null || entity.getParamValue().isEmpty()) {
                return ResponseDTO.error(RAGFlowApiConstants.ERROR_CODE_COMMON, "未找到默认聊天助手配置");
            }
            String chatId = entity.getParamValue();

            //TODO 登录用户
            String currentUserId = getUserId();
            if (userId != null) {
                userId = currentUserId;
            }
            return ragFlowService.listSessions(chatId, page, pageSize, orderBy, desc, name, id, userId);
        } catch (Exception e) {
            log.error("获取默认会话列表失败", e);
            return ResponseDTO.error(RAGFlowApiConstants.ERROR_CODE_COMMON, "获取默认会话列表失败：" + e.getMessage());
        }
    }

    /**
     * 删除聊天会话
     *
     * 删除指定聊天助手的会话。可以通过提供会话ID列表进行批量删除，
     * 如果未提供会话ID列表，则会删除该聊天助手的所有会话。
     *
     * @param chatId 聊天助手ID
     * @param request 包含会话ID列表的请求
     * @return 响应结果
     */
    @ApiOperation(value = "删除聊天会话", notes = "删除指定聊天助手的会话，可提供ID列表批量删除或删除所有会话")
    @DeleteMapping("/chats/{chatId}/sessions")
    public ResponseDTO<Void> deleteSessions(
            @ApiParam(value = "聊天助手ID", required = true) @PathVariable String chatId,
            @ApiParam(value = "会话ID列表", required = false) @RequestBody(required = false) Map<String, List<String>> request) {
        List<String> sessionIds = request != null ? request.get("ids") : null;
        return ragFlowService.deleteSessions(chatId, sessionIds);
    }

    /**
     * 与聊天助手对话
     *
     * 发送问题到聊天助手并获取回答。此接口可以创建新会话或在现有会话中继续对话。
     * 如果不提供sessionId，系统将创建新会话并返回新的sessionId。
     * 如果提供了sessionId，则在该会话中继续对话。
     * 可选启用流式输出模式，实时获取响应。
     *
     * @param chatId 聊天助手ID
     * @param request 聊天完成请求，包含问题内容、是否流式输出等参数
     * @param response HTTP响应，用于写入流式输出内容
     * @return 响应结果
     */
    @ApiOperation(value = "与聊天助手对话", notes = "发送问题到聊天助手并获取回答，支持创建新会话或在现有会话中继续对话")
    @PostMapping("/chats/{chatId}/completions")
    public ResponseEntity<?> chatCompletion(
            @ApiParam(value = "聊天助手ID", required = true) @PathVariable String chatId,
            @ApiParam(value = "聊天请求", required = true) @RequestBody Map<String, Object> request,
            HttpServletResponse response) throws IOException {
        CompletionRequestDTO completionRequest = new CompletionRequestDTO();
        completionRequest.setQuestion((String) request.get("question"));
        completionRequest.setStream((Boolean) request.get("stream"));
        completionRequest.setSessionId((String) request.get("sessionId"));
        completionRequest.setUserId((String) request.get("userId"));

        if(Objects.isNull(request.get("sessionId"))){
            throw new BizException("会话ID不能为空");
        }

        String userId = getUserId();
        if (userId != null) {
            completionRequest.setUserId(userId);
        }

        // 添加其他Begin组件指定的参数
        Map<String, Object> otherParams = new HashMap<>(request);
        otherParams.remove("question");
        otherParams.remove("stream");
        otherParams.remove("sessionId");
        otherParams.remove("userId");
        if (!otherParams.isEmpty()) {
            completionRequest.setOtherParams(otherParams);
        }

        // 处理流式输出
        Boolean isStream = completionRequest.getStream();
        if (isStream != null && isStream) {
            response.setContentType("text/event-stream");
            response.setCharacterEncoding("UTF-8");
            response.setHeader("Cache-Control", "no-cache");
            response.setHeader("Connection", "keep-alive");

            // 调用流式输出服务方法
            ragFlowService.streamChatCompletion(chatId, completionRequest, response);
            return ResponseEntity.ok().build(); // 已经通过response输出了流，这里直接返回
        } else {
            // 非流式输出，调用原来的方法
            ResponseDTO<Map<String, Object>> result = ragFlowService.chatCompletion(chatId, completionRequest);
            return ResponseEntity.ok(result);
        }
    }

    /**
     * 创建代理
     *
     * @param request 创建代理请求
     * @return 代理响应
     */
    @ApiOperation("创建代理")
    @PostMapping("/agents")
    public ResponseDTO<Map<String, Object>> createAgent(
            @ApiParam(value = "创建代理请求", required = true) @RequestBody Map<String, Object> request) {
        AgentRequestDTO agentRequest = new AgentRequestDTO();
        // 根据实际API填充AgentRequestDTO的字段
        agentRequest.setName((String) request.get("name"));
        agentRequest.setDescription((String) request.get("description"));
        agentRequest.setModel((String) request.get("model"));
        agentRequest.setInstructions((String) request.get("instructions"));

        // 转换工具和数据集ID
        @SuppressWarnings("unchecked")
        List<Map<String, Object>> tools = (List<Map<String, Object>>) request.get("tools");
        agentRequest.setTools(tools);

        @SuppressWarnings("unchecked")
        List<String> datasetIds = (List<String>) request.get("dataset_ids");
        agentRequest.setDataset_ids(datasetIds);

        return ragFlowService.createAgent(agentRequest);
    }

    /**
     * 获取代理
     *
     * @param agentId 代理ID
     * @return 代理响应
     */
    @ApiOperation("获取代理")
    @GetMapping("/agents/{agentId}")
    public ResponseDTO<Map<String, Object>> getAgent(
            @ApiParam(value = "代理ID", required = true) @PathVariable String agentId) {
        return ragFlowService.getAgent(agentId);
    }

    /**
     * 更新代理
     *
     * @param agentId 代理ID
     * @param request 更新代理请求
     * @return 代理响应
     */
    @ApiOperation("更新代理")
    @PutMapping("/agents/{agentId}")
    public ResponseDTO<Map<String, Object>> updateAgent(
            @ApiParam(value = "代理ID", required = true) @PathVariable String agentId,
            @ApiParam(value = "更新代理请求", required = true) @RequestBody Map<String, Object> request) {
        AgentRequestDTO agentRequest = new AgentRequestDTO();
        // 根据实际API填充AgentRequestDTO的字段
        agentRequest.setName((String) request.get("name"));
        agentRequest.setDescription((String) request.get("description"));
        agentRequest.setModel((String) request.get("model"));
        agentRequest.setInstructions((String) request.get("instructions"));

        // 转换工具和数据集ID
        @SuppressWarnings("unchecked")
        List<Map<String, Object>> tools = (List<Map<String, Object>>) request.get("tools");
        agentRequest.setTools(tools);

        @SuppressWarnings("unchecked")
        List<String> datasetIds = (List<String>) request.get("dataset_ids");
        agentRequest.setDataset_ids(datasetIds);

        return ragFlowService.updateAgent(agentId, agentRequest);
    }

    /**
     * 删除代理
     *
     * @param agentId 代理ID
     * @return 响应结果
     */
    @ApiOperation("删除代理")
    @DeleteMapping("/agents/{agentId}")
    public ResponseDTO<Void> deleteAgent(
            @ApiParam(value = "代理ID", required = true) @PathVariable String agentId) {
        return ragFlowService.deleteAgent(agentId);
    }

    /**
     * 获取代理列表
     *
     * @param page 页码
     * @param pageSize 每页大小
     * @param orderBy 排序字段
     * @param desc 是否降序
     * @param keywords 关键词
     * @return 代理列表响应
     */
    @ApiOperation("获取代理列表")
    @GetMapping("/agents")
    public ResponseDTO<AgentResponseDTO.AgentData> listAgents(
            @ApiParam(value = "页码") @RequestParam(required = false, defaultValue = "1") Integer page,
            @ApiParam(value = "每页大小") @RequestParam(required = false, defaultValue = "30") Integer pageSize,
            @ApiParam(value = "排序字段") @RequestParam(required = false) String orderBy,
            @ApiParam(value = "是否降序") @RequestParam(required = false) Boolean desc,
            @ApiParam(value = "关键词") @RequestParam(required = false) String keywords) {
        return ragFlowService.listAgents(page, pageSize, orderBy, desc, keywords);
    }


    /**
     * 创建代理会话
     *
     * 创建与代理的新会话，支持传递Begin组件指定的参数。
     * 可以通过application/json或multipart/form-data方式提交请求，
     * 后者用于需要上传文件的情况。
     *
     * @param agentId 代理ID
     * @param request 请求参数，包含Begin组件中指定的参数
     * @param userId 用户ID（可选）
     * @param file 上传的文件（可选）
     * @return 会话响应
     */
    @ApiOperation(value = "创建代理会话", notes = "创建与代理的新会话，支持传递Begin组件指定的参数和文件")
    @PostMapping("/agents/{agentId}/sessions")
    public ResponseDTO<Map<String, Object>> createAgentSession(
            @ApiParam(value = "代理ID", required = true) @PathVariable String agentId,
            @ApiParam(value = "请求参数", required = false) @RequestBody(required = false) Map<String, Object> request,
            @ApiParam(value = "用户ID", required = false) @RequestParam(required = false) String userId,
            @ApiParam(value = "上传的文件", required = false) @RequestParam(required = false) MultipartFile file) {
        // 如果请求体为null，初始化为空Map
        Map<String, Object> requestData = request != null ? request : new HashMap<>();
        return ragFlowService.createAgentSession(agentId, requestData, userId, file);
    }


    /**
     * 与代理对话
     *
     * 发送问题到代理并获取回答。此接口可以创建新会话或在现有会话中继续对话。
     * 如果不提供sessionId，系统将创建新会话并返回新的sessionId。
     * 如果提供了sessionId，则在该会话中继续对话。
     * 可选启用流式输出模式，实时获取响应。
     *
     * @param agentId 代理ID
     * @param request 聊天请求，包含问题内容、是否流式输出等参数
     * @param response HTTP响应，用于写入流式输出内容
     * @return 响应结果
     */
    @ApiOperation(value = "与代理对话", notes = "发送问题到代理并获取回答，支持创建新会话或在现有会话中继续对话")
    @PostMapping("/agents/{agentId}/completions")
    public ResponseEntity<?> agentCompletion(
            @ApiParam(value = "代理ID", required = true) @PathVariable String agentId,
            @ApiParam(value = "聊天请求", required = true) @RequestBody Map<String, Object> request,
            HttpServletResponse response) throws IOException {
        CompletionRequestDTO completionRequest = new CompletionRequestDTO();
        completionRequest.setQuestion((String) request.get("question"));
        completionRequest.setStream((Boolean) request.get("stream"));
        completionRequest.setSessionId((String) request.get("sessionId"));
        completionRequest.setUserId((String) request.get("userId"));

        String userId = getUserId();
        if (userId != null) {
            completionRequest.setUserId(userId);
        }

        // 添加其他Begin组件指定的参数
        Map<String, Object> otherParams = new HashMap<>(request);
        otherParams.remove("question");
        otherParams.remove("stream");
        otherParams.remove("sessionId");
        otherParams.remove("userId");
        if (!otherParams.isEmpty()) {
            completionRequest.setOtherParams(otherParams);
        }

        // 处理流式输出
        Boolean isStream = completionRequest.getStream();
        if (isStream != null && isStream) {
            response.setContentType("text/event-stream");
            response.setCharacterEncoding("UTF-8");
            response.setHeader("Cache-Control", "no-cache");
            response.setHeader("Connection", "keep-alive");

            // 调用流式输出服务方法
            ragFlowService.streamAgentCompletion(agentId, completionRequest, response);
            return ResponseEntity.ok().build(); // 已经通过response输出了流，这里直接返回
        } else {
            // 非流式输出，调用原来的方法
            ResponseDTO<Map<String, Object>> result = ragFlowService.agentCompletion(agentId, completionRequest);
            return ResponseEntity.ok(result);
        }
    }

    /**
     * 获取代理会话列表
     *
     * 获取指定代理的所有会话列表，支持分页、排序和筛选
     *
     * @param agentId 代理ID
     * @param page 页码，默认为1
     * @param pageSize 每页大小，默认为30
     * @param orderBy 排序字段，可选值：create_time(默认)、update_time
     * @param desc 是否降序，默认为true
     * @param id 要检索的会话ID
     * @param userId 要检索的用户ID
     * @return 会话列表响应，包含会话信息和消息
     */
    @ApiOperation(value = "获取代理会话列表", notes = "获取指定代理的所有会话列表，支持分页、排序和多种筛选条件")
    @GetMapping("/agents/{agentId}/sessions")
    public ResponseDTO<ThreadResponseDTO.ThreadData> listAgentSessions(
            @ApiParam(value = "代理ID", required = true) @PathVariable String agentId,
            @ApiParam(value = "页码，默认为1") @RequestParam(required = false, defaultValue = "1") Integer page,
            @ApiParam(value = "每页大小，默认为30") @RequestParam(required = false, defaultValue = "30") Integer pageSize,
            @ApiParam(value = "排序字段，可选值：create_time(默认)、update_time") @RequestParam(required = false) String orderBy,
            @ApiParam(value = "是否降序，默认为true") @RequestParam(required = false) Boolean desc,
            @ApiParam(value = "要检索的会话ID") @RequestParam(required = false) String id,
            @ApiParam(value = "要检索的用户ID") @RequestParam(required = false) String userId) {
        return ragFlowService.listAgentThreads(agentId, page, pageSize, orderBy, desc, id, userId);
    }

    private String getUserId() {
        String userId = null;
        MemberEntity byCurrentUser = memberService.getByCurrentUser(WebUtil.currentMember());
        if(Objects.nonNull(byCurrentUser) && Objects.nonNull(byCurrentUser.getRagFlowId())){
            userId = Objects.requireNonNull(byCurrentUser).getRagFlowId();
        }else {
            userId = Objects.requireNonNull(WebUtil.currentMember()).getId().toString();
        }
        return userId;
    }
}
